JBoss.orgCommunity Documentation

Chapter 10. MAP

10.1. SS7 Stack MAP
10.2. SS7 Stack MAP Usage

Mobile application part (MAP) is the protocol that is used to allow the GSM network nodes within the Network Switching Subsystem (NSS ) to communicate with each other to provide services, such as roaming capability, text messaging (SMS), Unstructured Supplementary Service Data ( USSD) and subscriber authentication. MAP provides an application layer on which to build the services that support a GSM network. This application layer provides a standardized set of services. MAP uses the services of the SS7 network, specifically the Signaling Connection Control Part (SCCP ) and the Transaction Capabilities Application Part (TCAP)

Important

For better understanding of this chapter please read GSM 09.02.

Note

JBoss Communications SS7 Stack MAP has implementation for USSD, SMS and Location Management Service (LMS) Messages only. Any contribution to implement other messages are welcome. We will provide you all the help that you may need initially.

The org.mobicents.protocols.ss7.map.api.MAPStack interface defines the methods required to represent MAP Protocol Stack. MAPStack exposes org.mobicents.protocols.ss7.map.api.MAPProvider that interacts directly with MAPStack. This interface defines the methods that will be used by any registered MAP User application implementing the org.mobicents.protocols.ss7.map.api.MAPDialogListener and org.mobicents.protocols.ss7.map.api.MAPServiceListener interface to listen MAP messages and dialogue handling primitives.

Each MAP-User interested in listening messages specific to MAP Service implements specific MAPServiceListener.

MAP-User interested in all the services may implement all the service listener class.

The org.mobicents.protocols.ss7.map.MAPStackImpl is concrete implementation of MAPStack. The MAP User application creates instance of MAPStackImpl passing the reference of SccpProvider and Sub System Number. All incoming messages are checked for destination SSN, if it matches with the one registered with this MAPStackImpl the corresponding listener is called else the peer receives error.

SccpProvider sccpProvider = getSccpProvider(); //JNDI lookup of SCCP Stack and get Provider

        MAPStackImpl mapStack = new MAPStackImpl(sccpPprovider, 8);
        ...
        

The reference to SccpProvider is received from SccpStack. To get handle to SccpStack do the JNDI look-up passing the JNDI name configured in SS7 service as explained in Section 8.3, “Access Point”

The MAP User application should register the concrete implementation of MAPDialogListener with MAPProvider to listen for incoming MAP Dialog and MAP Primitive messages.

The MAP User application should register the concrete implementation of MAPServiceListener with corresponding MAPServiceBase to listen for incoming MAP Service messages. Following MAPServiceBase are exposed by MAPProvider

  • For LSM service org.mobicents.protocols.ss7.map.api.service.lsm.MAPServiceLsm

  • For SMS service org.mobicents.protocols.ss7.map.api.service.sms.MAPServiceSms

  • For USSD service org.mobicents.protocols.ss7.map.api.service.supplementary.MAPServiceSupplementary



public class MAPExample implements MAPDialogListener, MAPServiceSupplementaryListener {
        .....       
        mapProvider = mapStack.getMAPProvider();
        mapProvider.addMAPDialogListener(this);
        mapProvider.getMAPServiceSupplementary().addMAPServiceListener(this);
        ....
} 
    

Before any MAP specific service can be used, the corresponding service should be activated



        .....       
        // Make the supplimentary service activated
        mapProvider.getMAPServiceSupplementary().acivate();
        ....
    

The MAP User Application leverages MapServiceFactory to create instance of USSDString and AddressString



        MapServiceFactory servFact = mapProvider.getMapServiceFactory();
        USSDString ussdString = servFact.createUSSDString("*125*+31628839999#",
                null);
        AddressString msisdn = this.servFact.createAddressString(
                AddressNature.international_number, NumberingPlan.ISDN,
                "31628838002");
    

The MAP User Application leverages specific MAPServiceBase to create new MAPDialog and send message



        // First create Dialog
        MAPDialogSupplementary mapDialog = mapProvider.getMAPServiceSupplementary().createNewDialog(
                MAPApplicationContext.getInstance(MAPApplicationContextName.networkUnstructuredSsContext, MAPApplicationContextVersion.version2), destAddress,
                destReference, origAddress, origReference);
        // The dataCodingScheme is still byte, as I am not exactly getting how
        // to encode/decode this.
        byte ussdDataCodingScheme = 0x0f;
        // USSD String: *125*+31628839999#
        // The Charset is null, here we let system use default Charset (UTF-7 as
        // explained in GSM 03.38. However if MAP User wants, it can set its own
        // impl of Charset
        USSDString ussdString = servFact.createUSSDString("*125*+31628839999#", null);
        AddressString msisdn = this.servFact.createAddressString(AddressNature.international_number,
                NumberingPlan.ISDN, "31628838002");
        mapDialog.addProcessUnstructuredSSRequest(ussdDataCodingScheme, ussdString, msisdn);
        // This will initiate the TC-BEGIN with INVOKE component
        mapDialog.send();
    

The complete example looks like



public class MAPExample implements MAPDialogListener, MAPServiceSupplementaryListener {
    private MAPStack mapStack;
    private MAPProvider mapProvider;
    MapServiceFactory servFact;
    SccpAddress destAddress = null;
    // The address created by passing the AddressNature, NumberingPlan and
    // actual address
    AddressString destReference = servFact.createAddressString(AddressNature.international_number,
            NumberingPlan.land_mobile, "204208300008002");
    SccpAddress origAddress = null;
    AddressString origReference = servFact.createAddressString(AddressNature.international_number, NumberingPlan.ISDN,
            "31628968300");
    MAPExample(SccpProvider sccpPprovider, SccpAddress address, SccpAddress remoteAddress) {
        origAddress = address;
        destAddress = remoteAddress;
        mapStack = new MAPStackImpl(sccpPprovider, 8);
        mapProvider = mapStack.getMAPProvider();
        servFact = mapProvider.getMapServiceFactory();
        mapProvider.addMAPDialogListener(this);
        mapProvider.getMAPServiceSupplementary().addMAPServiceListener(this);
    }
    private static SccpProvider getSccpProvider() throws NamingException {
        // no arg is ok, if we run in JBoss
        InitialContext ctx = new InitialContext();
        try {
            String providerJndiName = "/mobicents/ss7/sccp";
            return ((SccpStack) ctx.lookup(providerJndiName)).getSccpProvider();
        } finally {
            ctx.close();
        }
    }
    private static SccpAddress createLocalAddress() {
        return new SccpAddress(RoutingIndicator.ROUTING_BASED_ON_DPC_AND_SSN, 1, null, 8);
    }
    private static SccpAddress createRemoteAddress() {
        return new SccpAddress(RoutingIndicator.ROUTING_BASED_ON_DPC_AND_SSN, 2, null, 8);
    }
    public void run() throws Exception {
        // Make the supplimentary service activated
        mapProvider.getMAPServiceSupplementary().acivate();
        // First create Dialog
        MAPDialogSupplementary mapDialog = mapProvider.getMAPServiceSupplementary().createNewDialog(
                MAPApplicationContext.getInstance(MAPApplicationContextName.networkUnstructuredSsContext, MAPApplicationContextVersion.version2), destAddress,
                destReference, origAddress, origReference);
        // The dataCodingScheme is still byte, as I am not exactly getting how
        // to encode/decode this.
        byte ussdDataCodingScheme = 0x0f;
        // USSD String: *125*+31628839999#
        // The Charset is null, here we let system use default Charset (UTF-7 as
        // explained in GSM 03.38. However if MAP User wants, it can set its own
        // impl of Charset
        USSDString ussdString = servFact.createUSSDString("*125*+31628839999#", null);
        AddressString msisdn = this.servFact.createAddressString(AddressNature.international_number,
                NumberingPlan.ISDN, "31628838002");
        mapDialog.addProcessUnstructuredSSRequest(ussdDataCodingScheme, ussdString, msisdn);
        // This will initiate the TC-BEGIN with INVOKE component
        mapDialog.send();
    }
    public void onProcessUnstructuredSSIndication(ProcessUnstructuredSSIndication procUnstrInd) {
        // TODO Auto-generated method stub
    }
    public void onUnstructuredSSIndication(UnstructuredSSIndication unstrInd) {
        // TODO Auto-generated method stub
    }
    public static void main(String[] args) throws Exception {
        SccpProvider sccpProvider = getSccpProvider(); // JNDI lookup of SCCP
        SccpAddress localAddress = createLocalAddress();
        SccpAddress remoteAddress = createRemoteAddress();
        MAPExample example = new MAPExample(sccpProvider, localAddress, remoteAddress);
        example.run();
    }
    @Override
    public void onDialogRequest(MAPDialog mapDialog, AddressString destReference, AddressString origReference,
            MAPExtensionContainer extensionContainer) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onDialogAccept(MAPDialog mapDialog, MAPExtensionContainer extensionContainer) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onDialogReject(MAPDialog mapDialog, MAPRefuseReason refuseReason, MAPProviderError providerError,
            ApplicationContextName alternativeApplicationContext, MAPExtensionContainer extensionContainer) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onDialogUserAbort(MAPDialog mapDialog, MAPUserAbortChoice userReason,
            MAPExtensionContainer extensionContainer) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onDialogProviderAbort(MAPDialog mapDialog, MAPAbortProviderReason abortProviderReason,
            MAPAbortSource abortSource, MAPExtensionContainer extensionContainer) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onDialogClose(MAPDialog mapDialog) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onDialogDelimiter(MAPDialog mapDialog) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onDialogNotice(MAPDialog mapDialog, MAPNoticeProblemDiagnostic noticeProblemDiagnostic) {
        // TODO Auto-generated method stub
    }
    public void onDialogResease(MAPDialog mapDialog) {
        
    }
    @Override
    public void onDialogTimeout(MAPDialog mapDialog) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void onErrorComponent(MAPDialog mapDialog, Long invokeId, MAPErrorMessage mapErrorMessage) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void onProviderErrorComponent(MAPDialog mapDialog, Long invokeId, MAPProviderError providerError) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void onRejectComponent(MAPDialog mapDialog, Long invokeId, Problem problem) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void onInvokeTimeout(MAPDialog mapDialog, Long invoke) {
        // TODO Auto-generated method stub
        
    }
}